package org.mixim.examples.multiFreq;

import org.mixim.modules.nic.IWirelessNicUpperCtrl;
import org.mixim.base.modules.IBaseArp;
import org.mixim.base.modules.IBaseApplLayer;
import org.mixim.base.modules.IBaseNetwLayer;

import org.mixim.modules.netw.FlowMultiplexer;

module PhyMacHostMultiNic
{
    parameters:
        int numHosts; // total number of hosts in the network
        
        string networkType = default("BaseNetwLayer");       //type of the network layer
        string applicationType = default("BurstApplLayer");  //type of the application layer
        string mobilityType = default("StationaryMobility"); //type of the mobility module
        string arpType = default("BaseArp");                 //type of address resolution module
        string nicType= default("WirelessNic");
        int numNIC = default(1);                   // number of NICs
        int numAPP = default(1);                   // number of APPs
        @display("bgb=210,500,white;i=device/palm;b=40,40,rect");
        @node();
        
    gates:
        input radioIn[numNIC]; // gate for sendDirect
    submodules:
        arp: <arpType> like IBaseArp {
                @display("p=140,100;i=block/network2");
        }
        mobility: <mobilityType> like inet.mobility.IMobility {
            parameters:
                @display("p=140,30;i=block/cogwheel");
        }
        nic[numNIC]: <nicType> like IWirelessNicUpperCtrl {
            parameters:
                @display("p=70,450;i=block/wrxtx,#008000");
        }
        // OSI network layer
        netwl[numNIC]: <networkType> like IBaseNetwLayer {
            parameters:
                @display("p=70,380;i=block/layer");
        }
        // Flow Multiplexer
        multiplx: FlowMultiplexer {
            parameters:
                numOut = numNIC;
                numIn = numAPP;
                @display("p=70,310;i=block/classifier");
        }
        appl[numAPP]: <applicationType> like IBaseApplLayer {
            parameters:
                @display("p=70,30;i=app");
        }
    connections:
        for i=0..(numNIC-1) {
            nic[i].upperLayerOut --> netwl[i].lowerLayerIn;
        	nic[i].upperLayerIn <-- netwl[i].lowerLayerOut;
        	nic[i].upperControlOut --> { @display("ls=red;m=m,70,0,70,0"); } --> netwl[i].lowerControlIn;
        	nic[i].upperControlIn <-- { @display("ls=red;m=m,70,0,70,0"); } <-- netwl[i].lowerControlOut;
        	        	
            netwl[i].upperLayerOut --> multiplx.lowerMultiLayerIn[i];
        	netwl[i].upperLayerIn <-- multiplx.lowerMultiLayerOut[i];
        	netwl[i].upperControlOut --> { @display("ls=red;m=m,70,0,70,0"); } --> multiplx.lowerMultiControlIn[i];
        	netwl[i].upperControlIn <-- { @display("ls=red;m=m,70,0,70,0"); } <-- multiplx.lowerMultiControlOut[i];

            radioIn[i] --> nic[i].radioIn;
        }
   
        //# finaly we connect the highest existing layer of transport, session, or presentation to
        //# the application layer if specified
    	for i=0..(numAPP-1) {
            multiplx.upperMultiLayerOut[i] --> appl[i].lowerLayerIn;
            multiplx.upperMultiLayerIn[i] <-- appl[i].lowerLayerOut;
            multiplx.upperMultiControlOut[i] --> { @display("ls=red;m=m,70,0,70,0"); } --> appl[i].lowerControlIn;
            multiplx.upperMultiControlIn[i] <-- { @display("ls=red;m=m,70,0,70,0"); } <-- appl[i].lowerControlOut;
        }

}
